home *** CD-ROM | disk | FTP | other *** search
/ Amiga Developer CD v2.1 / Amiga Developer CD v2.1.iso / DevInfo / DeviceDevelopment / NSD-CommandSpecs < prev    next >
Text File  |  1997-05-15  |  21KB  |  544 lines

  1.  
  2.     $Id: NSD-CommandSpecs 1.6 1997/05/15 18:09:56 heinz Exp $
  3.  
  4.  
  5. NSD Command Space
  6. =================
  7.  
  8. As of January 1st, 1996, Amiga International, Inc. reserves two
  9. ranges in the set of command values for future enhancements. Only
  10. commands as specified by Amiga International, Inc. may be used
  11. here. It is illegal for a device developer to randomly "add" custom
  12. commands or command features in the reserved are!
  13.  
  14. There are 65536 command values possible with io_Command:
  15.  
  16.     $0000 - $3FFF       old style and 3rd party commands
  17.     $4000 - $7FFF       RESERVED AREA!
  18.     $8000 - $BFFF       old style and 3rd party commands
  19.     $C000 - $FFFF       RESERVED AREA!
  20.  
  21. To say it again: Commands in the reserved areas may only be
  22. assigned and specified by Amiga International, Inc.. Any "custom"
  23. implementation of these commands or other commands in these
  24. reserved areas is illegal and violates programming standards!
  25.  
  26.  
  27. Design Basis
  28. ============
  29.  
  30. A device driver is REQUIRED to return IOERR_NOCMD on any command it
  31. does not understand. This requirement is very old. It has been
  32. documented publically in 1991 already. If the device understands a
  33. command but the underlying HW can not handle it, IOERR_NOCMD should
  34. not be returned. IOERR_NOCMD should be an indicator for
  35. non supported, i.e., non-implemented, commands of the device, not
  36. for those that just cannot be executed due to environment
  37. constraints.
  38.  
  39.  
  40. What will new style commands do for you?
  41. ========================================
  42.  
  43. With old style devices it is impossible to find out about the type
  44. of device you are accessing. You don't know if the command set is
  45. serial.device like or trackdisk like. You don't know either what
  46. kind of request structure is appropriate. New style commands will
  47. let you query the device for its capabilities. As capabilities are
  48. added to a device, device users can use more features transparently
  49. without compatibility hacks.
  50.  
  51. There are two types of new style commands. "General" commands are
  52. the same for all new style devices. Depending on the device type
  53. there are device specific commands, too.
  54.  
  55. General commands will be defined in the range $4000-$7FFF, device
  56. specific commands are using the range $C000-$FFFF. It is illegal to
  57. use a device specific command before using the general commands to
  58. confirm the device's capabilities.
  59.  
  60. With a new style device, you can be sure that no 3rd party command
  61. will interact with the standard meaning of all the device's
  62. commands as documented for V40 of the OS.
  63.  
  64.  
  65. Basic requirements
  66. ==================
  67.  
  68. Let's make a quick list about the most basic requirements for any new
  69. style device. Keep it in mind when reading on.
  70.  
  71.     - IOERR_NOCMD support
  72.     - no redefinition of standard V40 or reserved commands
  73.     - no 3rd party commands in reserved areas
  74.     - NSCMD_DEVICEQUERY is supported
  75.     - lib_IdString must contain the name, version, and creation
  76.       date of the device and any other readable information to make
  77.       unique identification of a device for 3rd party command use
  78.       possible.
  79.     - Check mn_Length of the request on OpenDevice() for the minimum
  80.       required length
  81.  
  82. Some devices may have additional requirements. These will be listed
  83. in the sub document "NSD-DeviceSpecifics".
  84.  
  85.  
  86. Device Types
  87. ============
  88.  
  89. There are various types of devices in the V40 OS. audio.device is
  90. substantially different from serial.device, just like input.device
  91. is different from a SANA-II device like a2065.device. NSD does not
  92. want to describe the semantics behind each type of device. It puts
  93. the different V40 command sets needed for different types of
  94. devices into useful groups and tags these groups with an NSD device
  95. type identifier. This is to make sure that the existing standard
  96. V40 command set in each group is not redefined arbitrarily. The
  97. NSD device type identifier does not refer to specific
  98. functionality. User's of an NSD device must be able to fall back on
  99. these standard commands when they are implemented and get results
  100. that match usage of the respective V40 devices listed below. When a
  101. device is "like" a certain type mentioned, the emphasis is put on
  102. the the command set being alike to allow for grouping. Here is an
  103. annotated list of NSD device types, naming the respective V40
  104. devices and headers which define the command numbers that may not be
  105. redefined if they are implemented.
  106.  
  107. #define NSDEVTYPE_UNKNOWN       0   /* No suitable category, anything */
  108.     Any device that does not fit in a group mentioned below. Think
  109.     hard if you really need this category. Most likely you want an
  110.     exact identification then as described below to make sure what
  111.     you got. This category is dangerous as you can't say anything
  112.     about most of the old style command set without an exact NSD
  113.     identification.
  114.  
  115.         V40 Command Numbers: 1-8
  116.  
  117.  
  118. #define NSDEVTYPE_GAMEPORT      1   /* like gameport.device */
  119.     gameport.device     <devices/gameport.h>
  120.  
  121.         V40 Command Numbers: 1-13
  122.  
  123.  
  124. #define NSDEVTYPE_TIMER         2   /* like timer.device */
  125.     timer.device        <devices/timer.h>
  126.  
  127.         V40 Command Numbers: 1-11
  128.  
  129.  
  130. #define NSDEVTYPE_KEYBOARD      3   /* like keyboard.device */
  131.     keyboard.device     <devices/keyboard.h>
  132.  
  133.         V40 Command Numbers: 1-13
  134.  
  135.  
  136. #define NSDEVTYPE_INPUT         4   /* like input.device */
  137.     input.device        <devices/input.h>
  138.  
  139.         V40 Command Numbers: 1-16
  140.  
  141.  
  142. #define NSDEVTYPE_TRACKDISK     5   /* like trackdisk.device */
  143.     trackdisk.device    <devices/trackdisk.h>
  144.     scsi.device         <devices/scsidisk.h>
  145.     cd.device           <devices/cd.h>
  146.     mfm.device          similar to <devices/trackdisk.h>
  147.  
  148.         V40 Command Numbers: 1-23,28-29,32-46,
  149.                              $8002-$8005,$8009-$800B,$8010-$8011
  150.  
  151.  
  152.     The command sets of these three devices are sufficiently alike
  153.     to put them under a single label. It is expected that the
  154.     device interface for devices like these converge over time.
  155.  
  156. #define NSDEVTYPE_CONSOLE       6   /* like console.device */
  157.     console.device      <devices/console.h>
  158.  
  159.         V40 Command Numbers: 1-12
  160.  
  161.  
  162. #define NSDEVTYPE_SANA2         7   /* A >=SANA2R2 networking device */
  163.     any SANA-II device  <devices/sana2.h> (from the SANA-II archive)
  164.  
  165.         V40 Command Numbers: 1-26
  166.  
  167.  
  168. #define NSDEVTYPE_AUDIO         8   /* like audio.device */
  169.     audio.device        <devices/audio.h>
  170.  
  171.         V40 Command Numbers: 1-14,32
  172.  
  173.  
  174. #define NSDEVTYPE_CLIPBOARD     9   /* like clipboard.device */
  175.     clipboard.device    <devices/clipboard.h>
  176.  
  177.         V40 Command Numbers: 1-12
  178.  
  179.  
  180. #define NSDEVTYPE_PRINTER       10  /* like printer.device */
  181.     printer.device      <devices/printer.h>
  182.  
  183.         V40 Command Numbers: 1-12
  184.  
  185.  
  186. #define NSDEVTYPE_SERIAL        11  /* like serial.device */
  187.     serial.device       <devices/serial.h>
  188.  
  189.         V40 Command Numbers: 1-11
  190.  
  191.  
  192. #define NSDEVTYPE_PARALLEL      12  /* like parallel.device */
  193.     parallel.device     <devices/parallel.h>
  194.  
  195.         V40 Command Numbers: 1-10
  196.  
  197.  
  198.  
  199. The meaning of "No Command Redefinition"
  200. ========================================
  201.  
  202. An NSD device of a certain type is not allowed to redefine any V40
  203. command or any command from the NSD reserved ranges. Each NSD
  204. device type as described above groups the corresponding V40 devices
  205. with similar command sets. Each of these devices has an
  206. established, documented, and implemented set of commands with
  207. documented meaning. An NSD device must always handle all these
  208. commands, if implemented, like the respective V40 device or like
  209. the set of V40 devices for that NSD device type. It is not
  210. acceptable if a CMD_READ suddenly turns into functionality of
  211. CMD_WRITE or if HD_SCSICMD will suddenly be like a TD_EJECT. If you
  212. find, e.g., HD_SCSICMD or CD_INFO in the supported command list of a
  213. NSDEVTYPE_TRACKDISK device, you shall be sure that these commands
  214. behave like the V40 commands of the respective devices would
  215. behave. Note that if you find one command supported for an NSD
  216. device type, this does not mean that other commands for that NSD
  217. device type are necessarily supported. Check for the command set
  218. that you need.
  219.  
  220. For the common eight usable Exec standard commands, intentionally
  221. no distinction is made between different V40 devices which may fall
  222. under the same NSD device type. The device I/O operations should be
  223. consistent and uniform according to the RKM and NSD does not try to
  224. differentiate between possible execution differences for the Exec
  225. standard commands. Because of this requirement for consistency and
  226. uniformity, the standard Exec commands obviously may not be
  227. redefined arbitrarily either. If an Exec standard command is
  228. implemented in a device, the implementation must not deviate from
  229. the specification for that device type or common usage for that
  230. command.
  231.  
  232. All command slots that are not part of the V40 command set for the
  233. respective devices under the NSD device types or of the reserved
  234. NSD areas are free to be used for 3rd party extensions. NSD neither
  235. defines nor restricts their usage. From the NSD perspective, the
  236. meaning of any implemented 3rd party command is undefined. The user
  237. software is responsible for an exact device identification then to
  238. use 3rd party commands safely via the device's lib_IDString as
  239. described below.
  240.  
  241.  
  242. General commands
  243. ================
  244.  
  245. At the moment there is just a single new style general command:
  246.  
  247. #define NSCMD_DEVICEQUERY   0x4000
  248.  
  249. It is required for all new style devices.
  250.  
  251. You set up io_Data and io_Length pointing to a struct
  252. NSDeviceQueryResult below. You must clear SizeAvailable and set up
  253. DevQueryFormat before sending the command to the device. A new
  254. style device will set up the data in the buffer appropriately. If
  255. the command executed successfully the returned io_Actual value must
  256. be greater than zero and equal to the SizeAvailable value that has
  257. been set by the device. As with device usage in general, an
  258. io_Actual value that is alrger than the passed in io_Length value
  259. should be considered an error. The device may only be considered a
  260. new style device if these conditions are met. And only in this case
  261. the results of the query may be considered valid.
  262.  
  263. struct NSDeviceQueryResult
  264. {
  265.     /*
  266.     ** Standard information
  267.     */
  268.     ULONG   DevQueryFormat;         /* this is type 0               */
  269.     ULONG   SizeAvailable;          /* bytes available              */
  270.  
  271.     /*
  272.     ** Common information (READ ONLY!)
  273.     */
  274.     UWORD   DeviceType;             /* what the device does         */
  275.     UWORD   DeviceSubType;          /* depends on the main type     */
  276.     UWORD   *SupportedCommands;     /* 0 terminated list of cmd's   */
  277.  
  278.     /* May be extended in the future! Check SizeAvailable! */
  279. };
  280.  
  281. The device will fill in the struct NSDeviceQueryResult with read
  282. only data for the caller. All data must remain constant and valid
  283. as long as the device is open. After CloseDevice(), all bets are
  284. off.
  285.  
  286.     SizeAvailable
  287.  
  288.         Tells you how much of the structure contains valid data. It
  289.         is measured in bytes. Do not try to use fields in the
  290.         structure that are not fully included in the SizeAvailable
  291.         range. SizeAvailable must include SupportedCommands for any
  292.         successful query. So the minimum valid value is 16.
  293.  
  294.     DeviceType
  295.  
  296.         This tells you about the NSD type of device you are
  297.         accessing. The type names often match existing devices in
  298.         AmigaOS. If a device returns such a type, the device must
  299.         be able to at least handle all the documented features for
  300.         V40 of the operating system that the respective original
  301.         device has. If the NSD device type refers to a group of V40
  302.         devices, at least the basic command subset as for the
  303.         device named by the NSD device type shall be handled.
  304.  
  305.         Note well that while all the documented features for an
  306.         implemented command shall be handled, it is permissible
  307.         to return error codes or appropriate dummy returns for non
  308.         existing features in the NSD device as long as the handling
  309.         conforms to the original specification.
  310.  
  311.         If an old style or new style command cannot be supported in
  312.         a compatible manner, the device is required to return
  313.         IOERR_NOCMD for safety reasons. Modification of the
  314.         specification is not allowed. Add a 3rd party command if
  315.         needed.
  316.  
  317.         It is illegal to "reuse" command numbers of documented
  318.         standard commands that cannot be supported for other
  319.         purposes. E.g. a device driver of type NSDEVTYPE_TRACKDISK
  320.         that does not support TD_GETGEOMETRY and uses this command
  321.         for different functionality can never be a new style device
  322.         and may not support new style commands.
  323.  
  324.         It is also illegal to use the results of an
  325.         NSCMD_DEVICEQUERY without testing DeviceType first.
  326.  
  327.         The NSD device types are listed and explained above in the
  328.         section "Device Types".
  329.  
  330.         More types will be defined by Amiga International, Inc. as
  331.         necessary and requested. Each NSD device type represents a
  332.         certain command set that the device must handle. If the
  333.         type does not match a device that does exist in OS V40, the
  334.         exact requirements are defined below or in
  335.         "NSD-DeviceSpecifics". Note that some DeviceType entries
  336.         may cover multiple types of devices, so you have to check
  337.         the documentation carefully, when considering the standard
  338.         command set for a specific type.
  339.  
  340.     DeviceSubType
  341.  
  342.         There might be special incarnations of a device with
  343.         special capabilities beyond the standard set. At the moment
  344.         none are defined and a device is required to return 0 here.
  345.         As extensions that are marked by this field have to be
  346.         upwards compatible, this field need not be tested by users
  347.         who don't need any special capabilities beyond the standard
  348.         set. Otherwise it must be tested first.
  349.  
  350.     SupportedCommands
  351.  
  352.         This points to a 0 terminated list of io_Command values
  353.         that are supported by the device. This list must contain
  354.         all legal command values, old style, new style, and special
  355.         3rd party commands that are understood by the device and do
  356.         not cause an IOERR_NOCMD right away.
  357.  
  358.  
  359. You might notice the similarity to the SANA2-R2 (S2R2) S2_DEVICEQUERY
  360. command. It is intentional.
  361.  
  362. If you are developing software that needs to use 3rd party
  363. commands, you must try an *exact* 3rd party device identification
  364. via the lib_IdString in the device base and reject all devices that
  365. you don't know for a new style device.
  366.  
  367.  
  368. New Style Check in C
  369. ====================
  370.  
  371. A code fragment that could help you set up a new device query
  372. follows.
  373.  
  374.     struct IOStdReq *io;
  375.     struct NSDeviceQueryResult nsdqr;
  376.     LONG error;
  377.     BOOL newstyle = FALSE;
  378.     BOOL does64bit = FALSE;
  379.     BOOL doesETD64bit = FALSE;
  380.     UWORD *cmdcheck;
  381.     struct MsgPort *replyport;
  382.  
  383.     ...
  384.     /* See important *CAVEAT* below! */
  385.     io = CreateIORequest(replyport, sizeof(struct IOStdReq) + 128);
  386.     /* Add error checking in production code! */
  387.  
  388.     ...
  389.  
  390.     nsdqr.SizeAvailable  = 0;
  391.     nsdqr.DevQueryFormat = 0;
  392.  
  393.     io->io_Command = NSCMD_DEVICEQUERY;
  394.     io->io_Length  = sizeof(nsdqr);
  395.     io->io_Data    = (APTR)&nsdqr;
  396.     error = DoIO((struct IORequest *)io);
  397.     if((!error) &&
  398.        (io->io_Actual >= 16) &&
  399.        (io->io_Actual <= sizeof(nsdqr)) &&
  400.        (nsdqr.SizeAvailable == io->io_Actual))
  401.     {
  402.         /* Ok, this must be a new style device */
  403.         newstyle = TRUE;
  404.  
  405.         /* Device specific code follows here */
  406.         if(nsdqr.DeviceType == NSDEVTYPE_TRACKDISK)
  407.         {
  408.             /* Is it safe to use 64 bits with this driver? We can reject
  409.              * bad mounts pretty easily via this check!
  410.              */
  411.             for(cmdcheck = nsdqr.SupportedCommands;
  412.                 *cmdcheck;
  413.                 cmdcheck++)
  414.             {
  415.                 if(*cmdcheck == NSCMD_TD_READ64)
  416.                 {
  417.                     /* This trackdisk style device supports the basic
  418.                      * 64 bit command set without returning IOERR_NOCMD!
  419.                      */
  420.                     does64bit = TRUE;
  421.                 } /* if */
  422.  
  423.                 if(*cmdcheck == NSCMD_ETD_READ64)
  424.                 {
  425.                     /* This trackdisk style device supports the extended
  426.                      * 64 bit command set without returning IOERR_NOCMD!
  427.                      * According to specs, this implies does64bit == TRUE!
  428.                      */
  429.                     doesETD64bit = TRUE;
  430.                 } /* if */
  431.             } /* for */
  432.         } /* if */
  433.     } /* if */
  434.  
  435.  
  436. *** CAVEAT ***: There are some noteworthy points about this code
  437. fragment:
  438.  
  439. The check of io_Actual filters out anything that is obviously
  440. wrong. An NSD device may not return less than the minimum query
  441. structure and of course it may not try to return more than the
  442. buffer space available.
  443.  
  444. Error checking for request allocation has been left out for
  445. brevity. Obviously, production code should contain decent error
  446. checking code.
  447.  
  448. This code fragment uses a pointer to a struct IOStdReq to do the
  449. checks. Unfortunately, using a request of this size may result in
  450. severe problems with certain devices like SANA-II devices, which
  451. need a larger request structure. A current device should at minimum
  452. check in its OpenDevice() code if the passed in request is of at
  453. least the minimum required size to work with via its mn_Length
  454. field and fail to open if it isn't. This is a simple but effective
  455. paranoia check with the effect that surely broken request
  456. structures will be rejected right away. Unfortunately most devices
  457. don't do that check. Two basic assumptions can be relevant here:
  458.  
  459.     1. The trusting assumption
  460.  
  461.         You simply use the type and size of request structure
  462.         appropriate for the type of device you intend to use and
  463.         assume that the user did not give you the wrong type
  464.         of device. This may fail and result in a system crash.
  465.  
  466.     2. The safer assumption
  467.  
  468.         You use the type of request for the device type your are
  469.         expecting (or an IOStdReq for a general check) with an
  470.         extra 128 zeroed bytes when opening and checking a device.
  471.         This will be very safe as current devices are required to
  472.         check the minimum request length before opening
  473.         successfully. So any wrong type of device will not cause
  474.         problems here unless it both
  475.  
  476.             - uses a really strange long request that is
  477.               referenced on OpenDevice() time
  478.  
  479.         and
  480.  
  481.             - does not implement the required mn_Length check
  482.  
  483.         You only need that one larger request for the check on
  484.         opening the device. Afterwards you know what you are
  485.         working with and can use reasonably sized requests.
  486.  
  487. Obviously we cannot approve of the trusting assumption, because
  488. device access should be as safe as possible. So we require you to
  489. implement the safer assumption. Again, the basic idea behind this
  490. is that you should always strive to make device access as safe as
  491. possible. Some little things like validating the request structure
  492. on OpenDevice() will increase stability of the device system a lot
  493. at hardly any extra cost. Play it as safe as you can. The user
  494. might have some messed up code accessing the device!
  495.  
  496. It is wise to avoid writing devices that need arguments set up in
  497. the request structure for an OpenDevice() call. If you have to
  498. write a device like this, validate the request structure well
  499. and fail gracefully if you don't find the arguments needed.
  500.  
  501. It is valid and strongly suggested behaviour for a device to reject
  502. all new style commands except NSCMD_DEVICEQUERY with IOERR_NOCMD
  503. unless the caller executed a valid and successful NSCMD_DEVICEQUERY
  504. at least once before. This is intentionally stretching the meaning
  505. of IOERR_NOCMD to protect old software.
  506.  
  507.  
  508. Recommended use
  509. ===============
  510.  
  511. Anyone who wants to take advantage of the new style device
  512. interface should do this:
  513.  
  514.     - OpenDevice() as described above
  515.     - Try a NSCMD_DEVICEQUERY as described above
  516.     - If successful according to the rules mentioned above,
  517.       use the commands as listed in "SupportedCommands".
  518.     - Otherwise it must be an old style device. Hope and pray that
  519.       you got what you wanted.
  520.  
  521. Note: The above description and the code fragment shown assumes
  522. that you use OpenDevice() with a freshly created and appropriately
  523. initialised request structure. If you intend to reuse a previously
  524. used request structure for another OpenDevice() to make a general
  525. query, you should set at least the following fields to zero before
  526. calling OpenDevice(): io_Actual, io_Length, io_Data, io_Offset.
  527. It is strongly recommended to always do a query with a freshly set
  528. up request structure.
  529.  
  530.  
  531. Old Style and/or 3rd party vs. NSD
  532. ==================================
  533.  
  534. NSD conforming devices may only be identified via
  535. NSCMD_DEVICEQUERY. NSD does not make any judgements about old style
  536. devices or their usage. NSD does not make any judgements about
  537. 3rd party features within the NSD framework. If NSD is not
  538. available in a device, you are free to use other functionality as
  539. you see fit for the underlying old style device. If an NSD feature
  540. is not available, you are free to use other functionality not
  541. conflicting with the NSD specification.
  542.  
  543. *** EOT ***
  544.